<!--
 * @description 组件
 * @author: 陈陈
 * @date: 2025/05/09
 * @phone: 18560000860
 * @email: 18560000860@qq.com
 * @company: 济南晨霜信息技术有限公司 /
 * @business: 承接前后端项目的开发
-->
<template>
	<view
		class="pure-notice-bar-items-horizontal"
		:class="_classes"
		:style="_styles"
		:id="_cid"
	>
		<view
			:class="[
				'pure-notice-bar-items-horizontal__item',
				_uid,
				_current === _index ? 'pure-notice-bar-items-horizontal__item--move' : ''
			]"
			:style="_rects?.[_index]?.styles"
			v-for="(_item, _index) in list"
			:key="_index"
			@animationend="_onAnimationEnd(_index)"
			@tap="_handleClick(_index, _item)"
			:hoverClass="hoverClass"
		>
			{{ _item?.[labelKey] || _item }}
		</view>
	</view>
</template>

<script>
	import commonComponentOptions from "../../config/options";
	export default {
		options: commonComponentOptions
	};
</script>

<script setup>
	import { ref, computed, watch, nextTick, onMounted, getCurrentInstance } from "vue";
	import props from "./props";
	import { getRect, getRects, generateUUID, delay } from "@/uni_modules/pure-utils";

	const _cid = ref(generateUUID());
	const _uid = ref(generateUUID());
	const _instance = getCurrentInstance();
	// 容器宽度
	const _containerWidth = ref(0);
	// 激活项下标
	const _current = ref(-1);
	// 用于记录当前获取子节点布局信息的次数，总是使用最后一次获取的布局信息
	const _count = ref(0);
	// 子节点布局信息
	const _rects = ref([]);

	// -------------------------------------------------------------------------------- Props
	const _props = defineProps(props);

	// -------------------------------------------------------------------------------- Emits
	const _emits = defineEmits(["onItemClick"]);

	// -------------------------------------------------------------------------------- Classes
	const _classes = computed(() => {
		const array = [];
		return array;
	});

	// -------------------------------------------------------------------------------- Styles
	const _styles = computed(() => {
		const array = [];
		return array;
	});

	watch(
		() => _props.list,
		() => {
			_getRects();
		},
		{
			deep: true
		}
	);

	// 动画结束
	async function _onAnimationEnd(index) {
		// 贴边吸附模式
		if (_props.sticky) {
			// 停顿一下
			await delay(_props?.stickyDuration || 3000);
		}

		// 更新激活项下标
		if (index >= _props.list.length - 1) {
			_current.value = 0;
		} else {
			_current.value = index + 1;
		}
	}

	// 获取子节点布局信息
	async function _getRects() {
		if (!_props.list?.length) return;
		await nextTick();
		await delay(100);
		_current.value = -1;
		_rects.value = [];
		_count.value++;
		const count = _count.value;
		const rects = await getRects(`.${_uid.value}`, _instance);
		if (count === _count.value) {
			_rects.value = _calcStyles(rects);
			_current.value = 0;
		}
	}

	// 计算出样式
	function _calcStyles(rects = []) {
		rects.forEach((item) => {
			const styles = [];
			const width = item?.width || 0;

			// 移动用时
			styles.push(`--pure-notice-bar-item-move-duration: ${_calcDuration(width)}s`);

			// 目标 left 值
			styles.push(`--pure-notice-bar-item-to-left: ${_calcTarget(width)}px`);

			item.styles = styles;
		});
		return rects;
	}

	// 计算总用时
	function _calcDuration(width = 0) {
		if (width <= 0) {
			return 5;
		}

		// 贴边吸附模式
		if (_props.sticky) {
			return _containerWidth.value / _props.speed;
		}

		// 默认模式
		return (width + _containerWidth.value) / _props.speed;
	}

	// 计算出移动目标
	function _calcTarget(width = 0) {
		// 贴边吸附模式
		if (_props.sticky) {
			return 0;
		}

		// 默认模式
		return -width;
	}

	// 获取容器宽度
	async function _getContainerWidth() {
		await nextTick();
		await delay(20);
		const rect = await getRect(`#${_cid.value}`, _instance);
		_containerWidth.value = rect?.width || 0;
		_getRects();
	}

	// 点击事件
	function _handleClick(index, item) {
		_emits("onItemClick", index, item);
	}

	onMounted(() => {
		_getContainerWidth();
	});
</script>

<style scoped lang="scss">
	@import "./style.scss";
</style>
